using FT.Tweening.Core;
using FT.Tweening.Plugins.Options;

namespace FT.Tweening
{
    public interface IGuid
    {
        int Guid
        {
            get;
        }
    }

    public class GuidTween : IGuid
    {
        protected Tween mTween;

        protected bool checkIsNull()
        {
            if (mTween == null || mTween.Guid != Guid)
            {
                return true;
            }

            return false;
        }

        public Tween Value
        {
            get
            {
                if (checkIsNull())
                {
                    return null;    
                }

                return mTween;
            }
        }

        public GuidTween()
        {
            mTween = null;
            Guid = 0;
        }
        public GuidTween(Tween tween)
        {
            mTween = tween;
            Guid = tween.Guid;
        }

        public static implicit operator bool(GuidTween t)
        {
            return !t.checkIsNull();
        }
        
        public int Guid
        {
            get;
            protected set;
        }
        public override int GetHashCode()
        {
            return Guid;
        }

        public override bool Equals(object obj)
        {
            if (obj is IGuid guid)
            {
                return Guid == guid.Guid;
            }

            return false;
        }

        public void Setup(Tween t)
        {
            Guid = t.Guid;
            mTween = t;
        }
    }

    public class GuidTweener : GuidTween
    {
        public new Tweener Value
        {
            get
            {
                if (checkIsNull())
                {
                    return null;    
                }

                return mTween as Tweener;
            }
        }

        public GuidTweener()
        {
            mTween = null;
            Guid = 0;
        }
        public GuidTweener(Tweener t)
        {
            mTween = t;
            Guid = t.Guid;
        }

        public static implicit operator bool(GuidTweener t)
        {
            return !t.checkIsNull();
        }
    }

    public class GuidTweenerCore<T1, T2, TPlugOptions> : GuidTweener where TPlugOptions : struct, IPlugOptions
    {
        public new TweenerCore<T1, T2, TPlugOptions> Value
        {
            get
            {
                if (checkIsNull())
                {
                    return null;    
                }

                return mTween as TweenerCore<T1, T2, TPlugOptions>;
            }
        }

        public GuidTweenerCore()
        {
            mTween = null;
            Guid = 0;
        }
        public GuidTweenerCore(TweenerCore<T1, T2, TPlugOptions> t)
        {
            mTween = t;
            Guid = t.Guid;
        }

        public static implicit operator bool(GuidTweenerCore<T1,T2,TPlugOptions> t)
        {
            return !t.checkIsNull();
        }
    }
    
    
    public class GuidSequence : GuidTween
    {
        public new Sequence Value
        {
            get
            {
                if (checkIsNull())
                {
                    return null;    
                }

                return mTween as Sequence;
            }
        }

        public GuidSequence()
        {
            mTween = null;
            Guid = 0;
        }
        public GuidSequence(Tween sequence)
        {
            mTween = sequence;
            Guid = sequence.Guid;
        }

        public static implicit operator bool(GuidSequence t)
        {
            return !t.checkIsNull();
        }
    }
}